const fs = require('fs')
const path = require('path')

/**
 * 2020-10-27 sheyifan Issue: custom type
 * @typedef {{
 *		"待办": string,
 *		"保密": boolean,
 *		"事项说明": string,
 *		"标签": Array<string>,
 *		"风险": string,
 *		"完成状态": number,
 *		"完成说明": string,
 *		"资源求助": string
 * }} IssueItems - content od single issue
 * @typedef {{
 *		"日": string,
 *		"继承": boolean,
 *		"T0事项": Array<IssueItems>,
 *		"T1事项": Array<IssueItems>,
 *		"T2事项": Array<IssueItems>,
 *      "预约": {
 *          "T0事项": Array<IssueItems>,
 *		    "T1事项": Array<IssueItems>,
 *		    "T2事项": Array<IssueItems>,
 *      }
 * }} DayIssue - content of issues in single day
 * @typedef {{
 *     finish: number,
 *     undone: number
 * }} FinishData - state of issues
 * @typedef {{
 *     year: number,
 *     month: number,
 *     day: number,
 *     hour: number,
 *     minute: number,
 *     second: number,
 *     miliSecond: number,
 *     date: Date
 * }} Calendar
 * @typedef {{
 *     today: {
 *         T0: FinishData,
 *         T1: FinishData,
 *         T2: FinishData
 *     },
 *     days14: {
 *         data: Array<FinishData>
 *     },
 *     month6: {
 *         data: Array<FinishData>
 *     },
 *     thisWeek: {
 *         data: Array<number>
 *     }
 * }} RatioData
 */

/**
 * 2020-10-24 18.44 sheyifan Issue: get current data in JSON object
 * @param bias date which is relative to today by @param bias
 * @returns {Calendar} JSON object indicating current date
 */
function getDate(bias = 0) {
	let now = new Date()
	now.setDate(now.getDate() + bias)
	return {
		year: now.getFullYear(),
		month: now.getMonth() + 1,
		day: now.getDate(),
		hour: now.getHours(),
		minute: now.getMinutes(),
		second: now.getSeconds(),
		miliSecond: now.getMilliseconds(),
		date: now
	}
}

/**
 * 2020-10-28 sheyifan Issue: inherit from the former
 * @param {Date} date 
 * @returns {{
 *     t0: Array<IssueItems>,
 *     t1: Array<IssueItems>,
 *     t2: Array<IssueItems>
 * }} - all issues to be done
 */
function inherit(date) {
	/** @type {Array<IssueItems>} */
	let t0 = [];
	/** @type {Array<IssueItems>} */
	let t1 = [];
	/** @type {Array<IssueItems>} */
	let t2 = [];

	let now = null
	let searchDepth = 0
	let dateCopy = new Date(date)
	while (true) {
		now =  {
			year: date.getFullYear(),
			month: date.getMonth() + 1,
			day: date.getDate(),
			hour: date.getHours(),
			minute: date.getMinutes(),
			second: date.getSeconds(),
			miliSecond: date.getMilliseconds(),
			date: date
		}
		const filepath = path.resolve('./data/log', now.year.toString(), now.month.toString(), now.day.toString() + '.json')
		now.date.setDate(now.date.getDate() - 1)
		if (fs.existsSync(filepath)) {
			/** @type {DayIssue} */
			let dataTmp = JSON.parse(fs.readFileSync(filepath, { encoding: 'utf-8' }).toString())
			// 2020-10-31 sheyifan Attention: flag `继承` equals to `false` by default, which is defined in `createFile`
			if (dataTmp.继承 === false) {
				for (let issue0 of (dataTmp.T0事项 == undefined)?[]:dataTmp.T0事项) {
					if (issue0.完成状态 < 1 && issue0.完成状态 >= 0) {
						t0.push(issue0)
					}
				}
				for (let issue1 of (dataTmp.T1事项 == undefined)?[]:dataTmp.T1事项) {
					if (issue1.完成状态 < 1 && issue1.完成状态 >= 0) {
						t1.push(issue1)
					}
				}
				for (let issue2 of (dataTmp.T2事项 == undefined)?[]:dataTmp.T2事项) {
					if (issue2.完成状态 < 1 && issue2.完成状态 >= 0) {
						t2.push(issue2)
					}
				}

				if (dataTmp.预约 !== undefined) {
					for (let issue0 of (dataTmp.预约.T0事项 == undefined) ? [] : dataTmp.预约.T0事项) {
						// 2020-10-31 sheyifan Attention: statue of appointed issue should equals to 0
						if (issue0.完成状态 < 1 && issue0.完成状态 >= 0) {
							t0.push(issue0)
						}
					}
					for (let issue1 of (dataTmp.预约.T1事项 == undefined) ? [] : dataTmp.预约.T1事项) {
						// 2020-10-31 sheyifan Attention: statue of appointed issue should equals to 0
						if (issue1.完成状态 < 1 && issue1.完成状态 >= 0) {
							t1.push(issue1)
						}
					}
					for (let issue2 of (dataTmp.预约.T2事项 == undefined) ? [] : dataTmp.预约.T2事项) {
						// 2020-10-31 sheyifan Attention: statue of appointed issue should equals to 0
						if (issue2.完成状态 < 1 && issue2.完成状态 >= 0) {
							t2.push(issue2)
						}
					}
				}

				// Today cannot be inheritted
				if (searchDepth !== 0) {
					// change flag
					dataTmp.继承 = true
				}		
				try {
					if (searchDepth !== 0) {
						// `filepath` exists
						fs.writeFileSync(filepath, JSON.stringify(dataTmp, null, 4), 'utf-8')
					}
				} catch (e) {
					alert(e)
				}
			}
			// Data source file of current data has been inheritted
			else {
				break
			}
			// 2020-10-27 sheyifan Bug: dupicate data add into table and dashboard
			// Cause: depth also need to improve when file does not exist
			searchDepth++
		}
		else {
			// File does not exist, this day did not log anything. The next day
			searchDepth++
			// 2020-10-27 sheyifan Bug: dupicate data add into table and dashboard
			// Cause: depth also need to improve when file does not exist
			continue
		}
	}


	// 2020-10-30 10:17 sheyifan Issue: create new data source file when having not inherit from the former
	const filepath = path.resolve('./data/log', dateCopy.getFullYear().toString(), (dateCopy.getMonth() + 1).toString(), dateCopy.getDate().toString() + '.json')
	// 2020-10-30 10:16 sheyifan Attention: `inherit` -> `createFile`. If file exists, infer: having inheritted
	if (fs.existsSync(filepath)) {
		/** @type {DayIssue} */
		let dataOnDate = JSON.parse(fs.readFileSync(filepath, { encoding: 'utf-8' }).toString())
		return {
			t0: dataOnDate.T0事项,
			t1: dataOnDate.T1事项,
			t2: dataOnDate.T2事项
		}
	}
	
	// 2020-10-30 10:45 sheyifan Attention: `inherit` -> `createFile`. If file not exists, infer: having not inheritted
	let inherittedData = {
		t0: t0,
		t1: t1,
		t2: t2
	}
	createFile(dateCopy, inherittedData)

	return inherittedData
}

/**
 * 2020-10-29 01:24 sheyifan Issue: write @param issues into data source
 * file corresponding with @param date after inherit. If has been inheritted,
 * then return date of existing file at @param date 
 * @param {Date} date 
 * @param {{
 *     t0: Array<IssueItems>,
 *     t1: Array<IssueItems>,
 *     t2: Array<IssueItems>
 * }} issues - issues of different level
 * @returns {DayIssue} date written into data source file
 */
function createFile(date, issues) {
	// 2020-10-26 sheyifan 14:28 Issue: get data source file according to date
	const filepath = path.resolve('./data/log', date.getFullYear().toString(), (date.getMonth() + 1).toString(), date.getDate().toString() + '.json')

	// Issue data to be done today after inheritted from the former
	let nowDataAfterInherit = {
		"日": date.getDate().toString(),
		"继承": false,
		"T0事项": issues.t0,
		"T1事项": issues.t1,
		"T2事项": issues.t2,
		"预约": {
			"T0事项": [],
			"T1事项": [],
			"T2事项": [],
		}
	}
	if (!fs.existsSync(filepath)) {
		// 2020-10-26 20:40 sheyifan Issue: create directory recursively for necessary if file path do not exist
		try {
			// 2020-10-27 01:03 sheyifan Bug: folder name error
			fs.mkdirSync(path.dirname(filepath), { recursive: true })
		} catch (e) {
			console.log(e)
		}
	}
	// 2020-10-26 20:42 sheyifan Issue: write data to file (create file if necessary)
	fs.writeFileSync(filepath, JSON.stringify(nowDataAfterInherit, null, 4), 'utf-8')
	// 2020-10-28 00:55 sheyifan Issue: no need to close file after invoke writeFileSync()

	return nowDataAfterInherit
}

/**
 * 2020-10-26 sheyifan 16:08 Issue: add @param opts for overridding
 * 2020-10-26 sheyifan 20:13 Issue: create date source file today
 * if not exists. Inherrit the undone from the past and add them into
 * data source file today
 * 2020-10-27 sheyifan 18:08 Issue: change comment of this function to 
 * JSDoc for type annotation
 * @param {{
 *     year: number,
 *     month: number,
 *     day: number,
 *     hour: number,
 *     minute: number,
 *     second: number,
 *     milisecond: number
 * }} date - date of which render process ask for data
 * @param {{obj: Date}} opts - param for overridding
 * @returns {{
 *		"日": number,
 *		"继承": boolean,
 *		"T0事项": Array<IssueItems>,
 *		"T1事项": Array<IssueItems>,
 *		"T2事项": Array<IssueItems>
 * }} - data of corresponding date in JSON object
 */
function getDataByDate(date, opts) {
	let issues = null
	if(opts['obj']) {
		issues = inherit(new Date(opts.obj))
	}
	// 2020-10-30 10:50 sheyifan Attention: file path must exist after inherit
	// 2020-11-04 00:23 sheyifan Attention: file path may not exist when just finding without inherit
	/** @type {DayIssue} */
	let nowDataAfterInherit = null
	const filepath = path.resolve('./data/log', opts.obj.getFullYear().toString(), (opts.obj.getMonth() + 1).toString(), opts.obj.getDate().toString() + '.json')
	if (fs.existsSync(filepath)) {
		nowDataAfterInherit = JSON.parse(fs.readFileSync(filepath, { encoding: 'utf-8' }).toString())
	}

	return nowDataAfterInherit
}

/**
 * 2020-11-04 sheyifan Issue: just get data, no creating or modifying content of file
 * @param {Date} date 
 * @param {{
 *		"日": number,
 *		"继承": boolean,
 *		"T0事项": Array<IssueItems>,
 *		"T1事项": Array<IssueItems>,
 *		"T2事项": Array<IssueItems>
 * }} opt 
 * @returns {{
 *		"日": number,
 *		"继承": boolean,
 *		"T0事项": Array<IssueItems>,
 *		"T1事项": Array<IssueItems>,
 *		"T2事项": Array<IssueItems>
 * }}
 */
function getWithoutModify(date, opts) {
	let retData = {
		"日": 0,
		"继承": false,
		"T0事项": [],
		"T1事项": [],
		"T2事项": []
	}
	const filepath = path.resolve('./data/log', opts.obj.getFullYear().toString(), (opts.obj.getMonth() + 1).toString(), opts.obj.getDate().toString() + '.json')
	if (!fs.existsSync(filepath)) {
		return retData
	}
	
	return JSON.parse(fs.readFileSync(filepath, { encoding: 'utf-8' }).toString())
}

/**
 * 2020-10-27 17:09 sheyifan Issue: create this function for getting data into dashboard
 * 2020-10-27 18:48 sheyifan Issue: tranform to JSDoc for type annotation
 * @param {Date} date - instance of Date on current date 
 * @return {{
 *     today: {
 *         T0: FinishData,
 *         T1: FinishData,
 *         T2: FinishData
 *     },
 *     days14: {
 *         data: Array<FinishData>
 *     },
 *     month6: {
 *         data: Array<FinishData>
 *     },
 *     thisWeek: {
 *         data: Array<number>
 *     }
 * }}
 */
function getRadioByDate(date) {
	// 2020-10-29 01:59 Fail to create new data source file
	// Cause: `inherit` changed `date`. So need to pass a copy
	// of `date` as parameter of `inherit`
	inherit(new Date(date))

	let retObj = {
		today: {
			T0: {
				finish: 0,
				undone: 0
			},
			T1: {
				finish: 0,
				undone: 0
			},
			T2: {
				finish: 0,
				undone: 0
			}
		},
		days14: {
			/** @type {FinishData[]} */
			data:  []
		},
		month6: {
			/** @type {FinishData[]} */
			data: []
		},
		thisWeek: {
			/** @type {FinishData[]} */
			data: []
		}
	}

	const filepathToday = path.resolve('./data/log', date.getFullYear().toString(), (date.getMonth() + 1).toString(), date.getDate().toString() + '.json')
	if (fs.existsSync(filepathToday)) {
		/** @type {DayIssue}  */
		let dataToday = JSON.parse(fs.readFileSync(filepathToday, { encoding: 'utf-8' }).toString())
		// 2020-10-28 sheyifan Bug fix: handle undefined items
		for (let issue0 of (dataToday.T0事项 !== undefined)?dataToday.T0事项:[]) {
			if (issue0.完成状态 < 1 && issue0.完成状态 >= 0) {
				retObj.today.T0.undone++
			}
			else if (issue0.完成状态 === 1) {
				retObj.today.T0.finish++
			}
			else {
				console.log("Error: issue of invalid state.\n" + 
							"Year: " + date.getFullYear().toString() + ";\n" + "Month: " + date.getMonth().toString() + ";\n" + "Day: " + date.getDate().toString() +
							"Issue: " + issue0.待办 +
							"Issue desc: " + issue0.事项说明 + 
							"Invalid state: " + issue0.完成状态)
			}
		}
		// 2020-10-28 sheyifan Bug fix: handle undefined items
		for (let issue1 of (dataToday.T1事项 !== undefined)?dataToday.T1事项:[]) {
			if (issue1.完成状态 < 1 && issue1.完成状态 >= 0) {
				retObj.today.T1.undone++
			}
			else if (issue1.完成状态 === 1) {
				retObj.today.T1.finish++
			}
			else {
				console.log("Error: issue of invalid state.\n" + 
							"Year: " + date.getFullYear().toString() + ";\n" + "Month: " + date.getMonth().toString() + ";\n" + "Day: " + date.getDate().toString() +
							"Issue: " + issue1.待办 +
							"Issue desc: " + issue1.事项说明 + 
							"Invalid state: " + issue1.完成状态)
			}
		}
		// 2020-10-28 sheyifan Bug fix: handle undefined items
		for (let issue2 of (dataToday.T2事项 !== undefined)?dataToday.T2事项:[]) {
			if (issue2.完成状态 < 1 && issue2.完成状态 >= 0) {
				retObj.today.T2.undone++
			}
			else if (issue2.完成状态 === 1) {
				retObj.today.T2.finish++
			}
			else {
				console.log("Error: issue of invalid state.\n" + 
							"Year: " + date.getFullYear().toString() + ";\n" + "Month: " + date.getMonth().toString() + ";\n" + "Day: " + date.getDate().toString() +
							"Issue: " + issue2.待办 +
							"Issue desc: " + issue2.事项说明 + 
							"Invalid state: " + issue2.完成状态)
			}
		}
	}
	else {
		// use initial value
	}

	// 2020-10-28 18:56 Issue: get accomplishing state of the above seven days
	// 2020-10-29 02:43 Attention: the following functions will change `date`, 
	// so need to pass copy of date to function
	retObj.days14.data = toElevenDays(new Date(date))
	retObj.thisWeek.data = toThisWeek(new Date(date))
	retObj.month6.data = toSixMonths(new Date(date))

	return retObj
}

/**
 * 2020-10-27 sheyifan Issue: create function for iterate the above 14 days
 * @param {Date} date 
 * @returns {Array<FinishData>} finishing and undone state of recent 14 days
 */
function toElevenDays(date) {
	/** @type {Array<FinishData>} */
	let finishDataElevenDays = []

	for (let i = 0 ; i < 14 ; i++) {
		const filepathOnDate = path.resolve('./data/log', date.getFullYear().toString(), (date.getMonth() + 1).toString(), date.getDate().toString() + '.json')

		if (!fs.existsSync(filepathOnDate)) {
			date.setDate(date.getDate() - 1)
			finishDataElevenDays.push({
				finish: 0,
				undone: 0
			})
			continue
		}

		/** @type {DayIssue}  */
		let dataOnDate = JSON.parse(fs.readFileSync(filepathOnDate, { encoding: 'utf-8' }).toString())

		let finishCount= 0; let undoneCount = 0
		// 2020-10-28 sheyifan Bug fix: handle undefined items
		for (let issue0 of (dataOnDate.T0事项 !== undefined)?dataOnDate.T0事项:[]) {
			if (issue0.完成状态 < 1 && issue0.完成状态 >= 0) {
				undoneCount++
			}
			else if (issue0.完成状态 === 1) {
				finishCount++
			}
			else {
				console.log("Error: issue of invalid state.\n" + 
							"Year: " + date.getFullYear().toString() + ";\n" + "Month: " + date.getMonth().toString() + ";\n" + "Day: " + date.getDate().toString() +
							"Issue: " + issue0.待办 +
							"Issue desc: " + issue0.事项说明 + 
							"Invalid state: " + issue0.完成状态)
			}
		}
		// 2020-10-28 sheyifan Bug fix: handle undefined items
		for (let issue1 of (dataOnDate.T1事项 !== undefined)?dataOnDate.T1事项:[]) {
			if (issue1.完成状态 < 1 && issue1.完成状态 >= 0) {
				undoneCount++
			}
			else if (issue1.完成状态 === 1) {
				finishCount++
			}
			else {
				console.log("Error: issue of invalid state.\n" + 
							"Year: " + date.getFullYear().toString() + ";\n" + "Month: " + date.getMonth().toString() + ";\n" + "Day: " + date.getDate().toString() +
							"Issue: " + issue1.待办 +
							"Issue desc: " + issue1.事项说明 + 
							"Invalid state: " + issue1.完成状态)
			}
		}
		// 2020-10-28 sheyifan Bug fix: handle undefined items
		for (let issue2 of (dataOnDate.T2事项 !== undefined)?dataOnDate.T2事项:[]) {
			if (issue2.完成状态 < 1 && issue2.完成状态 >= 0) {
				undoneCount++
			}
			else if (issue2.完成状态 === 1) {
				finishCount++
			}
			else {
				console.log("Error: issue of invalid state.\n" + 
							"Year: " + date.getFullYear().toString() + ";\n" + "Month: " + date.getMonth().toString() + ";\n" + "Day: " + date.getDate().toString() +
							"Issue: " + issue2.待办 +
							"Issue desc: " + issue2.事项说明 + 
							"Invalid state: " + issue2.完成状态)
			}
		}
		finishDataElevenDays.push({
			finish: finishCount,
			undone: undoneCount
		})

		date.setDate(date.getDate() - 1)
	}

	return finishDataElevenDays
}

/**
 * 2020-10-29 02:42 sheyifan Issue: iterate this week for state of issues
 * @param {Date} date 
 * @returns {Array<FinishData>} finishing and undone state of this week
 */
function toThisWeek(date) {
	/** @type {Array<FinishData>} */
	let finishThisWeek = []

	for (let i = date.getDay() ; i > 0 ; i--) {
		const filepathOnDate = path.resolve('./data/log', date.getFullYear().toString(), (date.getMonth() + 1).toString(), date.getDate().toString() + '.json')

		if (!fs.existsSync(filepathOnDate)) {
			date.setDate(date.getDate() - 1)
			finishThisWeek.push({
				finish: 0,
				undone: 0
			})
			continue
		}

		/** @type {DayIssue}  */
		let dataOnDate = JSON.parse(fs.readFileSync(filepathOnDate, { encoding: 'utf-8' }).toString())

		let finishCount= 0; let undoneCount = 0
		// 2020-10-28 sheyifan Bug fix: handle undefined items
		for (let issue0 of (dataOnDate.T0事项 !== undefined)?dataOnDate.T0事项:[]) {
			if (issue0.完成状态 < 1 && issue0.完成状态 >= 0) {
				undoneCount++
			}
			else if (issue0.完成状态 === 1) {
				finishCount++
			}
			else {
				console.log("Error: issue of invalid state.\n" + 
							"Year: " + date.getFullYear().toString() + ";\n" + "Month: " + date.getMonth().toString() + ";\n" + "Day: " + date.getDate().toString() +
							"Issue: " + issue0.待办 +
							"Issue desc: " + issue0.事项说明 + 
							"Invalid state: " + issue0.完成状态)
			}
		}
		// 2020-10-28 sheyifan Bug fix: handle undefined items
		for (let issue1 of (dataOnDate.T1事项 !== undefined)?dataOnDate.T1事项:[]) {
			if (issue1.完成状态 < 1 && issue1.完成状态 >= 0) {
				undoneCount++
			}
			else if (issue1.完成状态 === 1) {
				finishCount++
			}
			else {
				console.log("Error: issue of invalid state.\n" + 
							"Year: " + date.getFullYear().toString() + ";\n" + "Month: " + date.getMonth().toString() + ";\n" + "Day: " + date.getDate().toString() +
							"Issue: " + issue1.待办 +
							"Issue desc: " + issue1.事项说明 + 
							"Invalid state: " + issue1.完成状态)
			}
		}
		// 2020-10-28 sheyifan Bug fix: handle undefined items
		for (let issue2 of (dataOnDate.T2事项 !== undefined)?dataOnDate.T2事项:[]) {
			if (issue2.完成状态 < 1 && issue2.完成状态 >= 0) {
				undoneCount++
			}
			else if (issue2.完成状态 === 1) {
				finishCount++
			}
			else {
				console.log("Error: issue of invalid state.\n" + 
							"Year: " + date.getFullYear().toString() + ";\n" + "Month: " + date.getMonth().toString() + ";\n" + "Day: " + date.getDate().toString() +
							"Issue: " + issue2.待办 +
							"Issue desc: " + issue2.事项说明 + 
							"Invalid state: " + issue2.完成状态)
			}
		}
		finishThisWeek.push({
			finish: finishCount,
			undone: undoneCount
		})

		date.setDate(date.getDate() - 1)
	}

	return finishThisWeek
}

/**
 * 2020-10-29 02:45 Issue: iterate 6 months for state of issues
 * @param {Date} date 
 * @returns {Array<FinishData>} finishing and undone state of recent 6 months
 */
function toSixMonths(date) {
	let initialDate = new Date(date)

	/** @type {Array<FinishData>} */
	let finishSixMonth = []
	// initialize
	for (let i = 0 ; i < 6 ; i++) {
		finishSixMonth.push({
			finish: 0,
			undone: 0
		})
	}

	while (true) {
		const filepathOnDate = path.resolve('./data/log', date.getFullYear().toString(), (date.getMonth() + 1).toString(), date.getDate().toString() + '.json')

		// 2020-10-29 sheyifan Issue: if current month equals to initial month minus 6 (if initial month minus 6 <= 0, then add 12). 
		if ((date.getMonth() + 1) === (((initialDate.getMonth() + 1 - 6) <= 0) ? (initialDate.getMonth() + 1 - 6 + 12):(initialDate.getMonth() + 1 - 6))) {
			break
		}

		if (!fs.existsSync(filepathOnDate)) {
			date.setDate(date.getDate() - 1)

			continue
		}

		/** @type {DayIssue}  */
		let dataOnDate = JSON.parse(fs.readFileSync(filepathOnDate, { encoding: 'utf-8' }).toString())

		let finishCount= 0; let undoneCount = 0
		// 2020-10-28 sheyifan Bug fix: handle undefined items
		for (let issue0 of (dataOnDate.T0事项 !== undefined)?dataOnDate.T0事项:[]) {
			if (issue0.完成状态 < 1 && issue0.完成状态 >= 0) {
				undoneCount++
			}
			else if (issue0.完成状态 === 1) {
				finishCount++
			}
			else {
				console.log("Error: issue of invalid state.\n" + 
							"Year: " + date.getFullYear().toString() + ";\n" + 
							"Month: " + date.getMonth().toString() + ";\n" + 
							"Day: " + date.getDate().toString() +
							"Issue: " + issue0.待办 +
							"Issue desc: " + issue0.事项说明 + 
							"Invalid state: " + issue0.完成状态)
			}
		}
		// 2020-10-28 sheyifan Bug fix: handle undefined items
		for (let issue1 of (dataOnDate.T1事项 !== undefined)?dataOnDate.T1事项:[]) {
			if (issue1.完成状态 < 1 && issue1.完成状态 >= 0) {
				undoneCount++
			}
			else if (issue1.完成状态 === 1) {
				finishCount++
			}
			else {
				console.log("Error: issue of invalid state.\n" + 
							"Year: " + date.getFullYear().toString() + ";\n" + 
							"Month: " + date.getMonth().toString() + ";\n" + 
							"Day: " + date.getDate().toString() +
							"Issue: " + issue1.待办 +
							"Issue desc: " + issue1.事项说明 + 
							"Invalid state: " + issue1.完成状态)
			}
		}
		// 2020-10-28 sheyifan Bug fix: handle undefined items
		for (let issue2 of (dataOnDate.T2事项 !== undefined)?dataOnDate.T2事项:[]) {
			if (issue2.完成状态 < 1 && issue2.完成状态 >= 0) {
				undoneCount++
			}
			else if (issue2.完成状态 === 1) {
				finishCount++
			}
			else {
				console.log("Error: issue of invalid state.\n" + 
							"Year: " + date.getFullYear().toString() + ";\n" + 
							"Month: " + date.getMonth().toString() + ";\n" + 
							"Day: " + date.getDate().toString() +
							"Issue: " + issue2.待办 +
							"Issue desc: " + issue2.事项说明 + 
							"Invalid state: " + issue2.完成状态)
			}
		}
		
		switch (date.getMonth() + 1) {
			// This month
			case initialDate.getMonth() + 1:
				finishSixMonth[0].finish += finishCount
				finishSixMonth[0].undone += undoneCount
				break
			// Above 1 month
			case ((initialDate.getMonth() + 1 - 1) <= 0) ? (initialDate.getMonth() + 1 - 1 + 12):(initialDate.getMonth() + 1 - 1):
				finishSixMonth[1].finish += finishCount
				finishSixMonth[1].undone += undoneCount
				break
			// Above 2 month
			case ((initialDate.getMonth() + 1 - 2) <= 0) ? (initialDate.getMonth() + 1 - 2 + 12):(initialDate.getMonth() + 1 - 2):
				finishSixMonth[2].finish += finishCount
				finishSixMonth[2].undone += undoneCount
				break
			// Above 3 month
			case ((initialDate.getMonth() + 1 - 3) <= 0) ? (initialDate.getMonth() + 1 - 3 + 12):(initialDate.getMonth() + 1 - 3):
				finishSixMonth[3].finish += finishCount
				finishSixMonth[3].undone += undoneCount
				break
			// Above 4 month
			case ((initialDate.getMonth() + 1 - 4) <= 0) ? (initialDate.getMonth() + 1 - 4 + 12):(initialDate.getMonth() + 1 - 4):
				finishSixMonth[4].finish += finishCount
				finishSixMonth[4].undone += undoneCount
				break
			// Above 5 month
			case ((initialDate.getMonth() + 1 - 5) <= 0) ? (initialDate.getMonth() + 1 - 5 + 12):(initialDate.getMonth() + 1 - 5):
				finishSixMonth[5].finish += finishCount
				finishSixMonth[5].undone += undoneCount
				break
		}


		date.setDate(date.getDate() - 1)
	}

	return finishSixMonth
}

module.exports = {
	getDate,
	getWithoutModify,
	getDataByDate,
	getRadioByDate
}